#include "networkManager.h"




networkManager::networkManager() {
    conTimer = 10;
    isConnected = 0;
    status = 0; //0= offline, 1=conected, 2=loggedin
    debug = 0;

    msg = NULL;
    gui = NULL;
    win = NULL;

    packet = NULL;
    peer = RakNetworkFactory::GetRakPeerInterface();
}

networkManager::~networkManager() {
    //dtor
}


void networkManager::IntroduceMessage(msgManager *pMsg) {
    msg = pMsg;
    if(debug>0) msg->Add("net: msg linked");

}

void networkManager::IntroduceGui(guiManager *pGui) {
    gui = pGui;
    if(debug>0) msg->Add("net: gui linked");

}

void networkManager::IntroduceWindows(windowManager *pWin) {
    win = pWin;
    if(debug>0) msg->Add("net: win linked");

}





void networkManager::Init(void) {

    SocketDescriptor SocketSetup;
    peer->Startup(1,30,&SocketSetup, 1);
    status=1;

}



void networkManager::Connect(string pHost) {

    peer->Connect(pHost.c_str(), 60000, 0,0);
    status=1;


    if(debug>0) msg->Add("net: Connecting");
    status=2;

}


void networkManager::sendMessage(int pType) {

    if(status>0) {

        char Nachricht[512]  = "";
        unsigned char systemType=ID_USER_PACKET_ENUM;


        RakNet::BitStream myBitStream;
        myBitStream.Write(systemType);
        myBitStream.Write(pType);

        // schuld be in CASE
        StructMsgLogin msgLogin;
        StructMsgChat tmpChatMessage;



        switch(pType) {


        case 100:       // PING:
            if(debug>1) msg->Add("net: Send PING.");
            break;


        case 101:      // PONG:
            if(debug>1) msg->Add("net: Send PONG.");
            break;


        case 104:      // KEEP_ALIVE (LAAG)
            //if(debug) ptrMsgEngine->Add("net: Send KEEP_ALIVE.");
            break;


        case 1:        // VERSION_ANSWER:
            unsigned short  version;
            if(debug>1) msg->Add("net: Send: VERSION_ANSWER.");
            version = 1;
            myBitStream.Write(version);
            break;


        case 3:        // LOGIN_ANSWER:
            msgLogin.name = win->windowGetEdit(8,0);
            msgLogin.pass = win->windowGetEdit(8,1);
            msgLogin.Write(&myBitStream);
            if(debug>1) msg->Add("net: Send: LOGIN_ANSWER.");
            break;


        case 5:        // CHAT:

            if(status>1) {
                tmpChatMessage.message = gui->chatInput;
                tmpChatMessage.sTime = "00:00";
                tmpChatMessage.Write(&myBitStream);
                if(debug>1) msg->Add("net: Send: CHAT.");
                gui->chatInput = "";
            }

            break;




        default:
            sprintf(Nachricht,"net: Send type unknown (%i)", pType);
            if(debug>0) msg->Add(Nachricht);
            break;
        }


        // Senden
        peer->Send(&myBitStream,HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true);

    }

}


void networkManager::readMessage(Packet *packet) {

    char Nachricht[512]  = "";
    int tmp=-1;
    int messageType;
    unsigned char systemType=0;


    StructMsgChat tmpChatMessage;
    StructMsgShowCharacters msgShowCharacters;

    // start reading
    RakNet::BitStream myBitStream(packet->data, packet->length, false);
    myBitStream.Read(systemType); // allways 77=ID_USER_PACKET_ENUM
    myBitStream.Read(messageType);

    switch(messageType) {

    case 100:       // PING:
        if(debug>1) msg->Add("net: Got PING");
        sendMessage(101); //PONG
        break;

    case 101:      // PONG:
        if(debug>1) msg->Add("net: Got PONG");
        break;








    case 0:         // VERSION_ASK:
        if(debug>1) msg->Add("net: Got VERSION_ASK");
        sendMessage(1); //VERSION_ANSWER
        break;


    case 2:         // LOGIN_ASK:
        if(debug>1) msg->Add("net: Got LOGIN_ASK");
        //TODO: function set todo into dynamishe liste
//        ptrDataCore->todo = 1;
        win->windowOpen(8);
        break;

    case 4:         // LOGIN_ANSWER:
        myBitStream.Read(tmp);
        if(tmp) {
            status=3;
            win->windowClose(8);
            msg->Add("Login successful");
        } else msg->Add("Login failed, try again");
        if(debug>1) msg->Add("net: Got: LOGIN_ANSWER");
        break;


    case 7:     // CHARACTER_ASK:

            msgShowCharacters.Read(&myBitStream);
            win->windowOpen(10);

            // do something

    break;





    case 5:     // CHAT
        tmpChatMessage.Read(&myBitStream);
        sprintf(Nachricht,"net-got: CHAT: (%s)", tmpChatMessage.message.c_str());
        if(debug>1) msg->Add(Nachricht);
        gui->InjectChat(tmpChatMessage.message);
        break;


    default:
        sprintf(Nachricht,"net: OwnPackage %i NOT handled!", messageType);
        if(debug>1) msg->Add(Nachricht);
        break;
    }


}





//void networkManager::sendData( void *data, int len ) {
void networkManager::Tick( void ) {

    if(status>0) {


        // recive packets
        packet=peer->Receive();
        char Nachricht[512]  = "";



        // work until stack is empty
        if(packet!=0) {

			switch (packet->data[0]) {

			case ID_REMOTE_DISCONNECTION_NOTIFICATION:
				if(debug>0) msg->Add("net: Another client has disconnected.");
				break;

			case ID_REMOTE_CONNECTION_LOST:
				if(debug>0) msg->Add("net: Another client has lost the connection.");
				break;

			case ID_REMOTE_NEW_INCOMING_CONNECTION:
				if(debug>0) msg->Add("net: Another client has connected.");
				break;

			case ID_CONNECTION_REQUEST_ACCEPTED:
				if(debug>0) msg->Add("net: Our connection request has been accepted.");
				break;

			case ID_NEW_INCOMING_CONNECTION:
				if(debug>0) msg->Add("net: A connection is incoming.");
				break;

			case ID_NO_FREE_INCOMING_CONNECTIONS:
				if(debug>0) msg->Add("net: The server is full.");
				break;

			case ID_DISCONNECTION_NOTIFICATION:
				if(debug>0) msg->Add("net: A client has disconnected.");
				break;

			case ID_CONNECTION_LOST:
				if(debug>0) msg->Add("net: A client lost the connection.");
				break;

			case ID_USER_PACKET_ENUM:
				//ptrMsgEngine->Add("net: OwnPackage income.");
				readMessage(packet);
				break;

			default:
			    sprintf(Nachricht,"net: Message with identifier %i has arrived.", packet->data[0]);
				if(debug>0) msg->Add(Nachricht);
				break;
			}

			peer->DeallocatePacket(packet);

		}
    }
}


void networkManager::TickSecond( void ) {
    if(status>0) sendMessage(104);
}


 int networkManager::getStatus(void) {
     return status;
 }


